#pragma once
#include <iostream>
using namespace std;
#include "Astar.h"


Astar::Astar()
{

	supplementaryMap[ROW][COLUMN] = { 0 };

	supplementaryMap[start_point.x][start_point.y] = true;
	linerDistance = 10;
	tiltDistance = 14;
	isEnd = false;




}
Astar::~Astar()
{

}

void Astar::printData()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COLUMN; j++)
		{
			cout << mapData[i][j] << " ";
		}
		cout << endl;
	}
}
int Astar::getH(Point end_point, Point position)
{
	int H = 10 * abs(end_point.x - position.x) + 10 * abs(end_point.y - position.y);
	return H;

}
bool Astar::addTree(Point position)
{
	if (position.x > ROW || position.x < 0
		|| position.y>COLUMN || position.y<0)
		return false;
	if (mapData[position.x][position.y] == 1)
		return false;
	if (supplementaryMap[position.x][position.y] == 1)
		return false;

	return true;


}

void Astar::Process()
{
	Tree* pNew = new Tree;
	memset(pNew, 0, sizeof(Tree));

	Tree* pRoot = pNew;
	pRoot->position = start_point;

	Tree* pCurrent = pRoot;
	cout << pCurrent->position.x << "," << pCurrent->position.y << endl;
	Tree* pChild = NULL;



	while (true)
	{

		// 1.find the point of move
		for (int i = 0; i < 8; i++)
		{
			pChild = new Tree;
			memset(pChild, 0, sizeof(Tree));
			pChild->position = pCurrent->position;
			switch (i)
			{
			case up:
				pChild->position.x--;
				pChild->position.G += linerDistance;
				break;
			case down:
				pChild->position.x++;
				pChild->position.G += linerDistance;
				break;
			case left:

				pChild->position.y--;
				pChild->position.G += linerDistance;
				break;
			case right:

				pChild->position.y++;
				pChild->position.G += linerDistance;
				break;
			case left_up:
				pChild->position.x--;
				pChild->position.y--;
				pChild->position.G += tiltDistance;
				break;
			case left_down:
				pChild->position.x++;
				pChild->position.y--;
				pChild->position.G += tiltDistance;
				break;
			case right_up:
				pChild->position.x--;
				pChild->position.y++;
				pChild->position.G += tiltDistance;
				break;
			case right_down:
				pChild->position.x++;
				pChild->position.y++;
				pChild->position.G += tiltDistance;
				break;
			default:
				break;

			}


			pChild->position.H = getH(end_point, pChild->position);
			cout << "(" << pChild->position.x << "," << pChild->position.y << " )" << ":" << pChild->position.G << ":" << pChild->position.H << endl;

			pChild->position.F = pChild->position.G + pChild->position.H;
			cout << "F=" << pChild->position.F << endl;

			//come into tree ,vector,mark has move
			if (addTree(pChild->position))
			{
				pCurrent->pChild.push_back(pChild);
				pChild->pFather = pCurrent;

				buff.push_back(pChild);
				supplementaryMap[pChild->position.x][pChild->position.y] = true;
			}
			else
			{
				delete pChild;
			}

		}
		//find the max point
		vector<Tree*>::iterator it;
		vector<Tree*>::iterator itMin;
		itMin = buff.begin();
		for (it = buff.begin(); it != buff.end(); it++)
		{
			itMin = (((*itMin)->position.F > (*it)->position.F) ? it : itMin);
		}

		pCurrent = *itMin;
		buff.erase(itMin);


		cout << "now is" << "(" << pCurrent->position.x << "," << pCurrent->position.y << ")" << endl;
        //the situation of break
		if (buff.empty())
		{
			isEnd = true;
			break;
		}
		if (pCurrent->position.x == end_point.x&&pCurrent->position.y == end_point.y)
		{
			isEnd = true;
			break;
		}



	}
	if (isEnd)
	{
		cout << "find the end point" << endl;
		while (pCurrent)
		{
			cout << "the trajectory is:" << endl;
			cout << "(" << pCurrent->position.x << "," << pCurrent->position.y << ")" << endl;
			pCurrent = pCurrent->pFather;
		}
	}
    delete pChild;
    delete pCurrent;

}